<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ReactFlow Example</title>
    <script src="https://cdn.jsdelivr.net/npm/babel-standalone@6.26.0/babel.min.js"></script>
    <script src="https://unpkg.com/react@17/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/reactflow@11.11.4/dist/umd/index.js"></script>
    <link href="https://unpkg.com/reactflow@11.11.4/dist/base.css" rel="stylesheet"/>
    <link href="https://unpkg.com/reactflow@11.11.4/dist/style.css" rel="stylesheet"/>
    <style>

           body {
       display: flex;
       justify-content: center;
       align-items: center;
       height: 100vh;
       margin: 0;
   }

   #root {
       width: 90vw;
       height: 90vh;
   }

    .text-updater-node{
        height:60px;
        width: 260px;
        background: 'white';
    }



    </style>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
        const { useCallback, useState } = React;
        const { applyNodeChanges, applyEdgeChanges, useNodesState, useEdgesState, addEdge, MiniMap, Controls, Background, Panel, NodeToolbar,Handle, Position  } = ReactFlow;
        const ReactFlow = ReactFlow.ReactFlow;

        // 自定义节点样式
        const style = {
          border: '1px solid #eee',
          padding: '5px 10px',
          borderRadius: '5px',
          background: 'white',
          background: '#06c',
          color: 'white',
          fontSize: '24px',
        }

        const CustomNode = ({ data }) => {
          return (
             <React.Fragment>
              <div style={style}>
                {data.label}
              </div>

              <Handle type="target" position={Position.Left} />
              <Handle type="source" position={Position.Right} />
              <Handle type="source" position={Position.Bottom} id="bottom"/>
              <Handle type="source" position={Position.Top} />
             </React.Fragment>
          );
        };

        const handleStyle = { left: 10 };
    // 自定义节点2
    function TextUpdaterNode({ data, isConnectable }) {
      const [val, setVal] = useState(data.value);
      const onChange = useCallback((evt) => {
        console.log(evt.target.value);
        setVal(evt.target.value);
      }, []);

      return (
        <div className="text-updater-node">
          <Handle
            type="target"
            position={Position.Top}
            isConnectable={isConnectable}
          />
          <div>
            <label htmlFor="text">处理数据:</label><br/>
            <input id="text" name="text" onChange={onChange} className="nodrag" value={val} />
          </div>
          <Handle
            type="source"
            position={Position.Bottom}
            id="a"
            style={handleStyle}
            isConnectable={isConnectable}
          />
          <Handle
            type="source"
            position={Position.Bottom}
            id="b"
            isConnectable={isConnectable}
          />
        </div>
      );
    }


        const nodeTypes = { textUpdater: CustomNode, textInput: TextUpdaterNode };

        const initialNodes = [
            {
            id: 'A',
            type: 'group',
            position: { x: 200, y: 20 },
            style: {
              width: 280,
              height: 240,
            },
          },
            { id: '1', position: { x: 140, y: 40 }, data: { label: '开始' }, type: 'textUpdater', parentId: 'A',
    extent: 'parent', },
            { id: '2', position: { x: 0, y: 140 }, data: { label: '处理数据' },  type: 'textInput', style: { backgroundColor: '#6ede87', color: 'white' }, parentId: 'A',
    extent: 'parent', },
            { id: '3', position: { x: 400, y: 250 }, data: { label: '分析结果' },  style: { backgroundColor: '#ff0072', color: 'white' }, },
            { id: '4', position: { x: 200, y: 350 }, data: { label: '生成报告' }, style: { backgroundColor: '#6865A5', color: 'white' }, },
            { id: '5', position: { x: 200, y: 450 }, data: { label: '结束' } },
        ];

        const initialEdges = [
            { id: 'e1-2', source: '1', target: '2' , type: 'smoothstep', animated: true, sourceHandle: 'bottom'},
            { id: 'e2-3', source: '2', target: '3', sourceHandle: 'b'},
            { id: 'e2-4', source: '2', target: '4', sourceHandle: 'a'},
            { id: 'e3-4', source: '3', target: '4' },
            { id: 'e4-5', source: '4', target: '5' },
        ];

        function Flow() {
            const [nodes, setNodes] = useNodesState(initialNodes);
            const [edges, setEdges] = useEdgesState(initialEdges);

              const onNodesChange = useCallback(
              (changes) => setNodes((nds) => applyNodeChanges(changes, nds)),
                [setNodes],
              );
              const onEdgesChange = useCallback(
                (changes) => setEdges((eds) => applyEdgeChanges(changes, eds)),
                [setEdges],
              );

            const onConnect = useCallback((params) => setEdges((eds) => addEdge(params, eds)), [setEdges]);
            const [variant, setVariant] = useState('lines');
            const rfStyle = {
              backgroundColor: '#B8CEFF',
            };
                const styles = {
                  background: 'black',
                  width: '100%',
                  height: 300,
                };
            return (
                <ReactFlow
                    nodes={nodes}
                    edges={edges}
                    onNodesChange={onNodesChange}
                    onEdgesChange={onEdgesChange}
                    onConnect={onConnect}
                    nodeTypes={nodeTypes}
                    colorMode="dark"
                    style={styles}
                    attributionPosition="top-right"
                 >
                 <MiniMap />
                  <Controls />
                  <Background />
                  <Panel position="right">
                  </Panel>
                  <NodeToolbar position="top"/>
                  <Background color="#ccc" variant={variant} />
                <Panel>
                  <div>修改背景:</div>
                  <button onClick={() => setVariant('dots')}>点</button>
                  <button onClick={() => setVariant('lines')}>网格线</button>
                  <button onClick={() => setVariant('cross')}>十字线</button>
                </Panel>

                </ReactFlow>
            );
        }

        function App() {
            return (<Flow />);
        }

        ReactDOM.render(<App />, document.getElementById('root'));

</script>
</body>
</html>